package io.gitee.dtdage.app.boot.starter.data.mybatis.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.gitee.dtdage.app.boot.starter.common.BaseEntity;
import io.gitee.dtdage.app.boot.starter.data.mybatis.context.PageBean;
import io.gitee.dtdage.app.boot.starter.data.mybatis.service.BaseService;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;

/**
 * 公共CRUD接口实现类
 *
 * @author WFT
 * @since 2024/4/14
 */
public abstract class BaseServiceImpl<T extends BaseEntity<? extends Serializable>, M extends BaseMapper<T>> implements BaseService<T> {

    /**
     * @noinspection SpringJavaAutowiredMembersInspection
     */
    @Autowired
    private M mapper;

    /**
     * @noinspection WeakerAccess
     */
    protected LambdaQueryWrapper<T> queryWrapper(Consumer<LambdaQueryWrapper<T>> consumer) {
        LambdaQueryWrapper<T> wrapper = Wrappers.lambdaQuery();
        consumer.accept(wrapper);
        return wrapper;
    }

    /**
     * @noinspection WeakerAccess
     */
    protected LambdaUpdateWrapper<T> updateWrapper(Consumer<LambdaUpdateWrapper<T>> consumer) {
        LambdaUpdateWrapper<T> wrapper = Wrappers.lambdaUpdate();
        consumer.accept(wrapper);
        return wrapper;
    }

    @Override
    public T create(T param) {
        if (this.mapper.insert(param) > 0) {
            return param;
        }
        throw new RuntimeException("数据插入异常");
    }

    @Override
    public void delete(Serializable masterKey) {
        this.mapper.deleteById(masterKey);
    }

    @Override
    public void delete(Collection<? extends Serializable> list) {
        this.mapper.deleteBatchIds(list);
    }

    @Override
    public void delete(Consumer<LambdaUpdateWrapper<T>> consumer) {
        this.mapper.delete(this.updateWrapper(consumer));
    }

    @Override
    public void update(T param) {
        this.mapper.updateById(param);
    }

    @Override
    public void update(T param, Consumer<LambdaUpdateWrapper<T>> consumer) {
        this.mapper.update(param, this.updateWrapper(consumer));
    }

    @Override
    public T get(Serializable masterKey) {
        return this.mapper.selectById(masterKey);
    }

    @Override
    public T get(Consumer<LambdaQueryWrapper<T>> consumer) {
        return this.mapper.selectOne(this.queryWrapper(consumer));
    }

    @Override
    public List<T> query(Consumer<LambdaQueryWrapper<T>> consumer) {
        return this.mapper.selectList(this.queryWrapper(consumer));
    }

    @Override
    public long count(Consumer<LambdaQueryWrapper<T>> consumer) {
        return this.mapper.selectCount(this.queryWrapper(consumer));
    }

    @Override
    public <Page extends PageBean<T>> Page page(Page page, Consumer<LambdaQueryWrapper<T>> consumer) {
        return this.mapper.selectPage(page, this.queryWrapper(consumer));
    }

}
